#pragma once
#include "stdafx.h"
#include "DeviceContext.h"
#include "Texture.h"

class Texture;
class DeviceContext;
class Component;

class Technique
{
private:
	Technique();
	
public:
	typedef boost::shared_ptr<Technique> sPtr;
	typedef boost::shared_ptr< Vector<D3D11_INPUT_ELEMENT_DESC> >  InputElementDescPtr;
	Technique(ID3DX11EffectTechnique*);
	~Technique();
	void Apply(boost::shared_ptr<DeviceContext>&);
	InputElementDescPtr GetLayoutDesc();
	D3DX11_EFFECT_SHADER_DESC GetVertexShaderDesc();

private:
	ID3DX11EffectPass* m_pass;
	ID3DX11EffectTechnique* m_technique;
	InputElementDescPtr  m_inputLayoutDesc;
	D3DX11_EFFECT_SHADER_DESC m_effectVertexShaderDesc;
	
};

class Effect : public Component
{
private:
	Effect();
	
public:
	typedef boost::shared_ptr<Effect> sPtr;
	typedef boost::unordered_map<string,Technique::sPtr> TechniuqeMap;
	Effect(ID3DX11Effect*);
	~Effect();
	void AddedToObject();
	void Initial();
	void SetDeviceContext(const Message&);
	Technique::InputElementDescPtr GetLayoutDesc(const string&);
	D3DX11_EFFECT_SHADER_DESC GetVertexShaderDesc(const string&);
	void SetMatrix(const string&,const XMMATRIX&);
	void SetResource(const string&, const Texture::sPtr&);
	void SetSampler(const string&, ID3D11SamplerState*);
	void Apply(const string&);

private:
	ID3DX11Effect* m_effect;
	boost::shared_ptr<DeviceContext> m_deviceContext;
	TechniuqeMap m_techniqueMap;
};